package com.hytech.utilities;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;



/**
 * GridView: a View-variant designed for handling the Grid for display with a base icon under
 * another icon. 
 * 
 */
public class GameGridView extends View {

	// GridSizes in pixels. 
    protected static int mGridSize;

    // count of grids in rows and columns.
    protected int mXGridCount;
    protected int mYGridCount;

    // any offset we need before the first grids.  
    protected int mXGridOffset;
    protected int mYGridOffset;


    // An array of Bitmaps to use to draw on each Grid. 
    protected Bitmap[] mGridElementArray;
    protected int mNumGridElements;
    
    // a generic bitmap to draw on each grid. 
    protected Bitmap mBaseGrid = null;

    protected Paint mPaint = new Paint();

    
    private static int phoneWidth = 0;
    private static int phoneLength = 0;
    
    /* 
     * A multi dimensional array, for the grids, which signify which mGridIndexs
     * entry should be used to draw that grid in the grid. 
     */
    protected int[][] mGridIndexs;



    public GameGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // start with a very basic grid size. 
        mGridSize = 24;
    }

    public GameGridView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mGridSize = 24; 
    }

    
    
    /**
     * Rests the internal array of Bitmaps used for drawing grids, and
     * sets the maximum index of grids to be inserted
     * 
     * @param gridcount
     */
    
    public void resetGrids(int gridcount) {
    	mGridElementArray = new Bitmap[gridcount];
    	mNumGridElements = gridcount;
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    	
    	phoneWidth = w;
    	phoneLength = h;
   
    	calculateGridSize();
    }
    
    /**
     * This is to get the grid Size when either the size changes, or the size of a grid changes.
     */
    protected void calculateGridSize() {

    	// let's start by calculating the number of grid elements here.
        mXGridCount = (int) Math.floor(phoneWidth / mGridSize);
        mYGridCount = (int) Math.floor(phoneLength / mGridSize);

        mXGridOffset = ((phoneWidth  - (mGridSize * mXGridCount)) / 2);
        mYGridOffset = ((phoneLength - (mGridSize * mYGridCount)) / 2);

        // create the game grid now. 
        mGridIndexs = new int[mXGridCount][mYGridCount];
        clearGrid();

    }

    /**
     * Function to set the specified Drawable as the grid for a particular
     * integer key.
     * 
     * @param key
     * @param gridDrawable
     */
    public void loadGrid(int key, Drawable gridDrawable) {
    	
    	if ( key < mNumGridElements ) {
        	// load the Bitmap and scale it to a Grid Size 
            Bitmap bitmap = Bitmap.createBitmap(mGridSize, mGridSize, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            gridDrawable.setBounds(0, 0, mGridSize, mGridSize);
            gridDrawable.draw(canvas);
            
            mGridElementArray[key] = bitmap;
    		
    	}
    }

    /**
     * Function to set the specified Drawable as the Base Grid element for all grid locations. 
     * 
     * @param gridDrawable
     */
    public void loadBaseGrid(Drawable gridDrawable) {
    	
    	// load the Bitmap and scale it to a Grid Size 
        Bitmap bitmap = Bitmap.createBitmap(mGridSize, mGridSize, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        gridDrawable.setBounds(0, 0, mGridSize, mGridSize);
        gridDrawable.draw(canvas);
        
        mBaseGrid = bitmap;
    }

    /**
     * Resets all grid locations to 0 (empty)
     * 
     */
    public void clearGrid() {
        for (int x = 0; x < mXGridCount; x++) {
            for (int y = 0; y < mYGridCount; y++) {
                setGridIndex(0, x, y);
            }
        }
        this.invalidate();
    }

    /**
     * Used to indicate that a particular grid location(set with loadGrid and referenced
     * by an integer) should be drawn at the given x/y coordinates during the
     * next invalidate/draw cycle.
     * 
     * NOTE: YOU MUST INVALIDATE THIS YOURSELF.. THIS DOES NOT INVALIDATE.
     * 
     * @param gridindex
     * @param x
     * @param y
     */
    public void setGridIndex(int gridindex, int x, int y) {
    	mGridIndexs[x][y] = gridindex;
    	
    }
    
    
    


    @Override
    public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
        for (int x = 0; x < mXGridCount; x += 1) {
            for (int y = 0; y < mYGridCount; y += 1) {
            	
            	if ( mBaseGrid != null ) {
            		// draw the base grid. 
            	
            		canvas.drawBitmap(mBaseGrid, 
            			mXGridOffset + x * mGridSize,
                		mYGridOffset + y * mGridSize,
                		mPaint);
            	}
                
            	int targetindex = mGridIndexs[x][y];
            	
            	if (targetindex > 0) {
                	if (targetindex < mNumGridElements && mGridElementArray[targetindex] != null) {
                	canvas.drawBitmap(mGridElementArray[targetindex], 
                    		mXGridOffset + x * mGridSize,
                    		mYGridOffset + y * mGridSize,
                    		mPaint);
                	}
                }
            }
        }

    }

    /**
     * findGridLocation: This takes an x and a y location and finds which 
     * grid location represents that. 
     * 
     * @param x the x component of the grid. 
     * @param y the y component of the grid. 
     * @return a Grid location for the grid.
     */
    protected GridLocation findGridLocation( int x, int y) {
    	GridLocation returnLocation = new GridLocation();
    	returnLocation.x = (x - mXGridOffset) / mGridSize;
    	returnLocation.y = (y - mYGridOffset) / mGridSize;
    	return returnLocation;
    }
    
    public static Bitmap scaleBitmap(Bitmap bm, int  newHeight, int  newWidth) {
    	
    	// let's get the width and height of the current bitmap.  Not the scaled width.
    	int width = bm.getWidth();
    	int height = bm.getHeight();
    	
    	// let's find what we will need to use to get the new size. 
    	float scaleWidth = ((float) newWidth) / width;
    	float scaleHeight =  ((float) newHeight) / height;
    	
    	// now we need a matrix to scale the bitmap. 
    	Matrix matrix = new Matrix();
    	matrix.postScale(scaleWidth, scaleHeight);
    	
    	// create a new bitmap that is of the new size. 
    	Bitmap scaledBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
    	
    	return scaledBitmap;
    }
}
